import {reactive, ref, Ref, UnwrapRef} from "vue";
import {GetArg1, GetReturnType, Union_as_xx} from "./通用Type";
import {TagNote, TagWrongCount} from "./Tags/OtherTag";
import {ITopic} from "./Topic";

/// 实际上我希望 Data 永远是 Ref<Data>
/// Data 独立出去
/// topic:ITopic<any> 是被标签的题目对象
export interface Tag<TagName extends string,Data>{
	tag_name:TagName;
	
	tag_color(self:Data,topic:ITopic<any>):'default' | 'primary' | 'info' | 'success' | 'warning' | 'error'|
		{ color?: string, borderColor?: string, textColor?: string }
	/// 显示的标签名
	/// 在这里 放入监听函数 ,你需要保证它只运行一次
	/// 我并不建议在这里 放入监听函数
	view(self:Data,topic:ITopic<any>): string
	
	// 这3个就差不多了,多了也麻烦
	on_click(event:any,self:Data,topic:ITopic<any>,...any:any[]):any
	on_click2(event:any,self:Data,topic:ITopic<any>,...any:any[]):any
	on_wheel(event:any,self:Data,topic:ITopic<any>,...any:any[]):any
	
	// 为存储服务
	data_as_storage(self:Data):any
	/// 这个self比较特殊
	/// 它的存在是为了满足 ITopic 的规则(永远不要覆盖字段值)
	/// 当然 ITopic 可能并没有 初始化 某个Tag
	/// 这个时候,我们就需要返回 Data 来填充(不是覆盖哦~)
	/// 事实上,我们希望,如果该类型需要 某个Tag,就初始化它,不然无法监听它的存在
	/// 虽然你也可以在 view 函数中 放入监听函数,但是它更加适合对于Tag使用,而不是类型
	/// 比如说: 自动存储 就可以 把监听函数放在 view 函数中
	storage_as_data(storage:any,self ?: Data):Data
}

/// 可定义的标签的集合
export type Tags = TagWrongCount | TagNote;


/// Name对应Data
type Tags_Data_1<T> = T extends Tag<infer TagName,infer Data> ? {
	[name in T["tag_name"]] ?: GetArg1<T["view"]>
} :never;
export type Tags_Data = Union_as_xx<Tags_Data_1<Tags>>;

/// Name对应NewFunction
type Tags_NewFunction_1<T> = T  extends Tag<infer TagName,infer Data> ? {
	[name in T["tag_name"] ]:T
}:never;
export type Tags_NewFunction = Union_as_xx<Tags_NewFunction_1<Tags>>;

/// Tag的产房
/// 由于存储并不附带对象,只附带Data,所以需要产房
export const TagsNewFunction:Tags_NewFunction= {
	TagNote: new TagNote(),
	TagWrongCount:new TagWrongCount()
}


